package com.wms_backend.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.wms_backend.dao.*;
import com.wms_backend.entity.*;
import com.wms_backend.service.OutboundService;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

@Service
public class OutboundServiceImpl implements OutboundService {
    @Autowired
    InboundDao inboundDao;

    @Autowired
    OutboundDao outboundDao;

    @Autowired
    UserDao userDao;

    @Autowired
    FloorDao floorDao;
    
    @Autowired
    ShelfDao shelfDao;

    @Override
    public Result create(JSONObject param, String userId) {
        Integer inboundId = param.getInteger("inboundId");
        Integer number = param.getInteger("number");
        Optional<Inbound> optionalInbound = inboundDao.findById(inboundId);
        Inbound inbound = optionalInbound.orElse(null);
        if (inbound.getRemainNumber() < number) {
            return Result.error("库存不足");
        } else {
            inbound.setOutNumber(inbound.getOutNumber() + number);
            inbound.setRemainNumber(inbound.getInNumber() - inbound.getOutNumber());
            inboundDao.save(inbound);
            Outbound outbound = new Outbound();
            outbound.setCreateUser(userId);
            outbound.setInboundId(inboundId);
            outbound.setNumber(number);
            outbound.setCreateTime(LocalDateTime.now().plusHours(8));
            outbound.setCompanyId(userDao.findByUserId(userId).orElse(null).getCompanyId());
            outboundDao.save(outbound);

            //腾出货架位置
            List<Integer> shelfIdList = new ArrayList<>();
            List<Floor> floorList = floorDao.findByInboundId(inboundId);
            for (Floor floor : floorList) {
                // 将inboundId设为null
                floor.setInboundId(null);

                // 将inboundOrder设为null
                floor.setInboundOrder(null);

                // 将status设为1
                floor.setStatus("1");

                Integer shelfId = floor.getShelfId();
                if (!shelfIdList.contains(shelfId)) {
                    shelfIdList.add(shelfId);
                }
            }
            floorDao.saveAll(floorList);

            List<Floor> filteredFloors = floorDao.findByShelfIdInAndStatus(shelfIdList, "1");
            Map<Integer, Integer> shelfIdCountMap = new HashMap<>();
            for (Floor floor : filteredFloors) {
                Integer shelfId = floor.getShelfId();
                if (shelfId != null) {
                    shelfIdCountMap.put(shelfId, shelfIdCountMap.getOrDefault(shelfId, 0) + 1);
                }
            }
            for (Map.Entry<Integer, Integer> entry : shelfIdCountMap.entrySet()) {
                Integer shelfId = entry.getKey();
                Integer count = entry.getValue();
                Integer status = null;
                if (count==10){
                    status=1;
                } else if (count <10 && count >0) {
                    status=2;
                } else if (count ==0) {
                    status=3;
                }
                Shelf shelf = shelfDao.findById(shelfId).orElse(null);
                shelf.setStatus(String.valueOf(status));
                shelfDao.save(shelf);
            }

            return Result.success();
        }

    }

    @Override
    public Result queryInbound(JSONObject param, String userId) {
        User user = userDao.findCompanyIdByUserId(userId);
        Integer companyId = user.getCompanyId();
        //获取JSON中的参数
        String createUser = param.getString("createUser");
        String name = param.getString("name");
        String kind = param.getString("kind");
        //按条件查询
        Specification<Inbound> sc = new Specification<Inbound>() {
            @Override
            public Predicate toPredicate(Root<Inbound> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                if (createUser != null) {
                    list.add(cb.like(root.get("createUser"), "%" + createUser + "%"));
                }
                if (name != null) {
                    list.add(cb.like(root.get("name"), "%" + name + "%"));
                }
                if (kind != null) {
                    list.add(cb.like(root.get("kind"), "%" + kind + "%"));
                }
                list.add(cb.equal(root.get("status"), 2)); //质检合格已入库订单
                list.add(cb.equal(root.get("companyId"), companyId));
                Predicate[] predicates = new Predicate[list.size()];
                list.toArray(predicates);
                return cb.and(predicates);
            }
        };
        List<Inbound> result = inboundDao.findAll(sc);
        return Result.success(result);
    }


    @Override
    public Result queryByCondition(JSONObject param, String userId) {
        User user = userDao.findCompanyIdByUserId(userId);
        Integer companyId = user.getCompanyId();
        //获取JSON中的参数
        String createUser = param.getString("createUser");
        Integer inboundId = param.getInteger("inboundId");
        Integer number = param.getInteger("number");
        Integer pageNum = param.getInteger("pageNum");
        Integer pageSize = param.getInteger("pageSize");
        //按条件查询
        Specification<Outbound> sc = new Specification<Outbound>() {
            @Override
            public Predicate toPredicate(Root<Outbound> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                if (createUser != null) {
                    list.add(cb.like(root.get("createUser"), "%" + createUser + "%"));
                }
                if (inboundId != null) {
                    list.add(cb.equal(root.get("inboundId"), inboundId));
                }
                if (number != null) {
                    list.add(cb.equal(root.get("number"), number));
                }
                list.add(cb.equal(root.get("companyId"), companyId));
                Predicate[] predicates = new Predicate[list.size()];
                list.toArray(predicates);
                return cb.and(predicates);
            }
        };
        if (pageSize == null || pageNum == null) {
            pageNum = 1;
            pageSize = 10;
        }
        Page<Outbound> result = outboundDao.findAll(sc, PageRequest.of(pageNum - 1, pageSize));
        List<Outbound> content = result.getContent();
        List<OutboundDetails> message = new ArrayList<>();
        for (Outbound outbound : content) {
            Optional<Inbound> inbounds = inboundDao.findById(outbound.getInboundId());
            Inbound inbound = inbounds.get();
            OutboundDetails outboundDetails = new OutboundDetails();
            outboundDetails.setId(outbound.getId());
            outboundDetails.setCreateUser(outbound.getCreateUser());
            outboundDetails.setInboundId(outbound.getInboundId());
            outboundDetails.setNumber(outbound.getNumber());
            outboundDetails.setCreateTime(outbound.getCreateTime());
            outboundDetails.setCompanyId(outbound.getCompanyId());
            outboundDetails.setKind(inbound.getKind());
            outboundDetails.setName(inbound.getName());
            message.add(outboundDetails);
        }
        Page<OutboundDetails> od = new PageImpl<>(message, PageRequest.of(pageNum - 1, pageSize), result.getTotalElements());
        return Result.success(od);
    }
}
